package com.wwl.base.common.excel.json;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;

/**
 * @author wwl
 * @version 1.0
 * @date 2021/2/8 14:55
 * @description:
 */
public abstract class JSON {
    private static final ObjectMapper DEFAULT_MAPPER = createObjectMapper();

    /**
     * 使用默认配置创建ObjectMapper
     * <p>
     * 注意：可以在一定范围内共享示例以提高性能，但不能将ObjectMapper设置为全局变量以避免污染（比如在某段代码中修改了ObjectMapper导致其他不相关业务故障）
     *
     * @return 每次调用此方法都会返回一个新的ObjectMapper
     */
    public static ObjectMapper createObjectMapper() {
        return new ObjectMapper()
                .registerModule(new Jdk8Module())
                .registerModule(new JavaTimeModule())
                .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
                .configure(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS, true)
                .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    public static String toJSONString(Object value) {
        try {
            return DEFAULT_MAPPER.writeValueAsString(value);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public static String toJSONStringWithDateFormat(Object value, String dateFormat) {
        try {
            ObjectMapper objectMapper = createObjectMapper();
            objectMapper.setDateFormat(new SimpleDateFormat(dateFormat));
            return objectMapper.writeValueAsString(value);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public static JSONObject toJSONObject(Object value) {
        return DEFAULT_MAPPER.convertValue(value, JSONObject.class);
    }

    public static JSONArray toJSONArray(List<?> list) {
        return DEFAULT_MAPPER.convertValue(list, JSONArray.class);
    }

    public static JSONObject parseObject(String content) {
        return parseObject(content, JSONObject.class);
    }

    public static <T> T parseObject(String content, Class<T> clazz) {
        try {
            return DEFAULT_MAPPER.readValue(content, clazz);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> T parseObject(String content, JavaType type) {
        try {
            return DEFAULT_MAPPER.readValue(content, type);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static <T> T parseObject(String content, TypeReference<T> typeReference) {
        try {
            return DEFAULT_MAPPER.readValue(content, typeReference);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static JSONArray parseArray(String content) {
        return parseObject(content, JSONArray.class);
    }

    public static <T> List<T> parseArray(String content, Class<T> elementClass) {
        return parseObject(content, TypeFactory.defaultInstance().constructCollectionType(List.class, elementClass));
    }

}
